package com.cmict.data.infra.service.message;

import com.cmict.data.framework.common.pojo.PageResult;
import com.cmict.data.framework.security.core.util.AESUtil;
import com.cmict.data.framework.security.core.util.RSAUtils;
import com.cmict.data.framework.tenant.core.context.TenantContextHolder;
import com.cmict.data.infra.api.message.dto.MessageDTO;
import com.cmict.data.infra.controller.admin.message.vo.AnnouncementDTO;
import com.cmict.data.infra.controller.admin.vo.MessageTemplateCreateReqVO;
import com.cmict.data.infra.controller.admin.vo.MessageTemplateExportReqVO;
import com.cmict.data.infra.controller.admin.vo.MessageTemplatePageReqVO;
import com.cmict.data.infra.controller.admin.vo.MessageTemplateUpdateReqVO;
import com.cmict.data.infra.convert.message.MessageTemplateConvert;
import com.cmict.data.infra.dal.dataobject.message.MessageTemplateDO;
import com.cmict.data.infra.dal.mysql.message.MessageTemplateMapper;
import com.cmict.data.infra.utils.FreeMarkerUtil;
import com.cmict.data.system.api.conf.ConfApi;
import com.cmict.data.system.api.conf.dto.ConfSystemDTO;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;

import static com.cmict.data.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cmict.data.infra.enums.message.ErrorCodeConstants.MESSAGE_TEMPLATE_NOT_EXISTS;
import static com.cmict.data.infra.enums.message.ErrorCodeConstants.MESSAGE_TEMPLATE_USE_FAILED;

/**
 * 信息模板 Service 实现类
 *
 * @author liutao
 * @date 2022/5/11
 */
@Service
@Validated
public class MessageTemplateServiceImpl implements MessageTemplateService {

    @Resource
    private MessageTemplateMapper messageTemplateMapper;

    @Resource
    private AnnouncementService announcementService;

    @Resource
    private ConfApi confApi;

    @Override
    public Long createMessageTemplate(MessageTemplateCreateReqVO createReqVO) {
        // 插入
        MessageTemplateDO messageTemplate = MessageTemplateConvert.INSTANCE.convert(createReqVO);
        messageTemplateMapper.insert(messageTemplate);
        // 返回
        return messageTemplate.getId();
    }

    @Override
    public void updateMessageTemplate(MessageTemplateUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateMessageTemplateExists(updateReqVO.getId());
        // 更新
        MessageTemplateDO updateObj = MessageTemplateConvert.INSTANCE.convert(updateReqVO);
        messageTemplateMapper.updateById(updateObj);
    }

    @Override
    public void deleteMessageTemplate(Long id) {
        // 校验存在
        this.validateMessageTemplateExists(id);
        // 删除
        messageTemplateMapper.deleteById(id);
    }

    private void validateMessageTemplateExists(Long id) {
        if (messageTemplateMapper.selectById(id) == null) {
            throw exception(MESSAGE_TEMPLATE_NOT_EXISTS);
        }
    }

    @Override
    public MessageTemplateDO getMessageTemplate(Long id) {
        return messageTemplateMapper.selectById(id);
    }

    @Override
    public List<MessageTemplateDO> getMessageTemplateList(Collection<Long> ids) {
        return messageTemplateMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<MessageTemplateDO> getMessageTemplatePage(MessageTemplatePageReqVO pageReqVO) {
        return messageTemplateMapper.selectPage(pageReqVO);
    }

    @Override
    public List<MessageTemplateDO> getMessageTemplateList(MessageTemplateExportReqVO exportReqVO) {
        return messageTemplateMapper.selectList(exportReqVO);
    }


    @Override
    public Boolean sendMessageByTemplate(MessageDTO messageDTO) {
        // 租户为 1 时 才有 消息模板 拿到消息模板后，再进行还原 原始租户
        Long tenantId = TenantContextHolder.getTenantId();
//        TenantContextHolder.setTenantId(1L);
        validateMessageTemplateExists(messageDTO.getTemplateId());
        MessageTemplateDO templateDO = messageTemplateMapper.selectById(messageDTO.getTemplateId());
//        TenantContextHolder.setTenantId(tenantId);
        //组装信息
        String content = null;
        try {
            content = FreeMarkerUtil.process(templateDO.getContent(), messageDTO.getParam());
        } catch (Exception e) {
            throw exception(MESSAGE_TEMPLATE_USE_FAILED);
        }
        AnnouncementDTO announcementDTO = new AnnouncementDTO();
        BeanUtils.copyProperties(templateDO, announcementDTO);
        BeanUtils.copyProperties(messageDTO, announcementDTO);
        announcementDTO.setContent(content);
        announcementDTO.setReceiveMode(messageDTO.getChannel());
        if(messageDTO.getTemplateId() .equals( 14L ) || messageDTO.getTemplateId().equals(15L) || messageDTO.getTemplateId().equals(16L)){
            announcementDTO.setReceiveMode(templateDO.getChannel());
        }else{
            announcementDTO.setReceiveMode(messageDTO.getChannel());
        }
        announcementDTO.setTemplateId(messageDTO.getTemplateId());
        announcementDTO.setContentDisplay(templateDO.getContentDisplay());
        announcementDTO.setIsRemind(messageDTO.getIsRemind());
        announcementDTO.setTime(messageDTO.getTime());
        announcementDTO.setMessage(messageDTO.getMessage());
        announcementDTO.setFrequency(messageDTO.getFrequency());
        announcementDTO.setCompleterFrequency(messageDTO.getCompleterFrequency());
        announcementDTO.setRemindId(messageDTO.getRemindId());
        return announcementService.addAnnouncement(announcementDTO);
    }

    @Override
    public Long getTemplateByTitle(String title) {
        return   messageTemplateMapper.getTemplateByTitle(title);
    }

    @Override
    public Boolean testEmail(ConfSystemDTO confValueByConfKey) {
//        ConfSystemDTO confValueByConfKey = confApi.getConfValueByConfKey(ConfKeyEnum.SYSTEM_EMAIL.getConfKey());
        String[] emails = {confValueByConfKey.getEmailAccount()};
        try {
            HtmlEmail email = new HtmlEmail();
            // 这里是SMTP发送服务器的名字：163的如下："smtp.163.com"
            email.setHostName(confValueByConfKey.getEmailSMTPService());
            email.setSmtpPort(Integer.valueOf(confValueByConfKey.getEmailSMTPPort()));
//            if (true) {  // isSSL
//                email.setSSLOnConnect(true);
//                email.setSmtpPort(465);
//            }
            // 字符编码集的设置
            email.setCharset("UTF-8");
            // 收件人的邮箱
            email.addTo(emails);
            // 发送人的邮箱以及发件人名称

            email.setFrom(confValueByConfKey.getEmailAccount(), confValueByConfKey.getEmailName());

            // 如果需要认证信息的话，设置认证：用户名-密码。分别为发件人在邮件服务器上的注册名称和密码
            String password = RSAUtils.decrypt(confValueByConfKey.getEmailPassword());
            if(password.startsWith(AESUtil.ENCRYPT_FLAG)){
                email.setAuthentication(confValueByConfKey.getEmailAccount(), AESUtil.decrypt(password));
            }else{
                email.setAuthentication(confValueByConfKey.getEmailAccount(), password);
            }
            // 要发送的邮件主题
            email.setSubject("测试连接");
            // 要发送的信息，由于使用了HtmlEmail，可以在邮件内容中使用HTML标签
            email.setHtmlMsg("测试连接");

            String result1 = email.send();
            return true;
        } catch (EmailException e) {
            e.printStackTrace();
            return false;
        }
    }


}
